package com.ruoyi.web.controller.work;

import cn.hutool.core.io.resource.ResourceUtil;
import com.alibaba.fastjson2.JSON;
import com.itextpdf.text.pdf.PdfReader;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisLock;
import com.ruoyi.common.exception.file.FileUploadException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.work.config.PdfSignatureConfig;
import com.ruoyi.work.domain.KeywordInfo;
import com.ruoyi.work.domain.Stamp;
import com.ruoyi.work.service.IPdfService;
import com.ruoyi.work.utils.PdfUtils;
import com.ruoyi.work.utils.TransparentImageUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotBlank;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 操作pdf盖章
 *
 * @author fengcheng
 */
@RestController
@RequestMapping("/file/pdf")
@Validated
public class PdfController extends BaseController {

    @Autowired
    private IPdfService pdfService;

    @Autowired
    private RedisLock redisLock;

    @Autowired
    private PdfSignatureConfig pdfSignatureConfig;

    private static final String PDF_COUNTERSIGN = "pdf_countersign";

    /**
     * 完成盖章和签名
     *
     * @param stampList
     * @return
     */
    @PostMapping("/complete")
    public AjaxResult complete(@RequestBody List<Stamp> stampList) {
        redisLock.lock(PDF_COUNTERSIGN);
        try {
            pdfService.completeStamp(stampList);
        } finally {
            redisLock.unlock(PDF_COUNTERSIGN);
        }
        return AjaxResult.success();
    }

    /**
     * 完成加盖骑缝章
     *
     * @return
     */
    @PostMapping("/completeRidingSeal")
    public AjaxResult completeRidingSeal(@RequestBody Stamp stamp) throws IOException {
        boolean b;

        // 获取pdf文件路径
        String localPath = RuoYiConfig.getProfile();
        String pathPdf = StringUtils.substringAfter(stamp.getFilePath(), Constants.RESOURCE_PREFIX);

        String inputPdfPathPdf = localPath + pathPdf;
        String outPdfPathPdf = localPath + "/temp" + pathPdf;

        // 获取章图片路径
        String inputPdfPathSura = localPath + StringUtils.substringAfter(stamp.getImagesUrl(), Constants.RESOURCE_PREFIX);

        PdfSignatureConfig pdfSignatureConfig1 =
                new PdfSignatureConfig(
                        ResourceUtil.getStream(pdfSignatureConfig.getPath()),
                        pdfSignatureConfig.getPassword(),
                        pdfSignatureConfig.getName(),
                        pdfSignatureConfig.getPhone(),
                        pdfSignatureConfig.getPlace(),
                        pdfSignatureConfig.getCause());
        redisLock.lock(PDF_COUNTERSIGN);
        try {
            b = PdfUtils.generatePagingSeal(pdfSignatureConfig1, inputPdfPathPdf, outPdfPathPdf, inputPdfPathSura, stamp.getX(), stamp.getY(), stamp.getWidth(), stamp.getHeight(), localPath);
        } finally {
            redisLock.unlock(PDF_COUNTERSIGN);
        }
        return toAjax(b);
    }

    /**
     * 通过关键字获取xy
     *
     * @param filePath 文档id
     * @param keyword  关键字
     * @return Result
     */
    @GetMapping("/keyword")
    public AjaxResult getSealLocation(String filePath, String keyword) {
        // 本地资源路径
        String localPath = RuoYiConfig.getProfile();
        // 数据库资源地址
        String loadPath = localPath + StringUtils.substringAfter(filePath, Constants.RESOURCE_PREFIX);

        try (InputStream io = Files.newInputStream(Paths.get(loadPath))) {
            List<KeywordInfo> list = pdfService.getSealLocation(new PdfReader(io), keyword);
            return AjaxResult.success(list);
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 生成骑缝章图片
     *
     * @param suraImg 印章路径
     * @param page    pdf总页数
     * @return
     */
    @GetMapping("/generatePagingSeal")
    public AjaxResult generatePagingSeal(String suraImg, int page) {
        // 本地资源路径
        String localPath = RuoYiConfig.getProfile();
        // 数据库资源地址
        String loadPath = localPath + StringUtils.substringAfter(suraImg, Constants.RESOURCE_PREFIX);

        List<HashMap<String, Object>> map = new ArrayList<>();

        // 获取文件后缀
        String fileExtension = FileUploadUtils.getFileExtension(loadPath);

        String name = new File(loadPath).getName();
        String nameWithoutExtension = name.substring(0, name.lastIndexOf("."));

        try {
            BufferedImage[] images = PdfUtils.getImage(loadPath, page, null, null);
            for (int i = 0; i < page; i++) {
                HashMap<String, Object> hashMap = new HashMap<String, Object>(16);

                BufferedImage image = images[i];
                String filePath = localPath + "/sura/" + nameWithoutExtension + (i + 1) + "." + fileExtension;
                File outputFile = new File(filePath);

                if (!outputFile.exists()) {
                    outputFile.mkdirs();
                }
                ImageIO.write(image, fileExtension, outputFile);


                if (TransparentImageUtils.changeImgColor(filePath, filePath.replace(FileUploadUtils.getFileExtension(filePath), "png"))) {
                    String fileName = "/sura" + "/" + outputFile.getName();
                    hashMap.put("url", Constants.RESOURCE_PREFIX + fileName);
                    hashMap.put("page", i + 1);
                    map.add(hashMap);
                } else {
                    throw new FileUploadException("处理失败");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error();
        }
        return AjaxResult.success(map);
    }

    /**
     * 获取pdf大纲
     *
     * @param filePath
     * @return
     */
    @GetMapping("/getPdfOutline")
    public AjaxResult getPdfOutline(@NotBlank(message = "filePath为空") String filePath) {
        // 本地资源路径
        String localPath = RuoYiConfig.getProfile();
        // 数据库资源地址
        String downloadPath = localPath + StringUtils.substringAfter(filePath, Constants.RESOURCE_PREFIX);
        List<HashMap<String, Object>> outlines = pdfService.getPdfOutline(downloadPath);
        return AjaxResult.success(outlines);
    }


    /**
     * 获取pdf指定页图片,返回给前端图片
     *
     * @param filePath 文档路径
     * @param page     页码
     * @param response
     * @throws IOException
     */
    @Anonymous
    @GetMapping("/img")
    public void img(String filePath, Integer page, HttpServletResponse response)
            throws IOException {
        // 本地资源路径
        String localPath = RuoYiConfig.getProfile();
        // 数据库资源地址
        String downloadPath = localPath + StringUtils.substringAfter(filePath, Constants.RESOURCE_PREFIX);

        PDDocument doc = PDDocument.load(new File(downloadPath));
        PDFRenderer renderer = new PDFRenderer(doc);
        int pageCount = doc.getNumberOfPages();
        if (page - 1 > pageCount) {
            //返回结果
            response.setContentType("application/json");
            response.setCharacterEncoding("UTF-8");
            // 获取PrintWriter对象
            PrintWriter out = response.getWriter();
            out.print(JSON.toJSONString(AjaxResult.error()));
            // 释放PrintWriter对象
            out.flush();
            out.close();
            return;
        }
        response.setContentType("image/jpeg");
        // 不缓存此内容
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expire", 0);

        BufferedImage image = renderer.renderImage(page - 1, 2f);
        ImageIO.write(image, "JPEG", response.getOutputStream());
        doc.close();
    }
}
